﻿using System;
using System.Collections.Generic;
using System.Linq;
using YawetagDemo.Framework.Data;
using YawetagDemo.Framework.Impl.Data;
using YawetagDemo.Framework.Services;
using YawetagLib.System.Data;
using YawetagLib.System.Services;

namespace YawetagDemo.Framework.Impl.Services
{
    public class CoreService : BaseService, ICoreService
    {
        public CoreService(IServiceFactory serviceFactory, IDataManager dataManager)
            : base(serviceFactory, dataManager)
        {
        }

        internal Person GetPerson(int personID)
        {
            return DataManager.Get<PersonRepository>().Get(personID);
        }

        IPerson ICoreService.GetPerson(int personID)
        {
            return GetPerson(personID);
        }

        internal IList<Person> GetPersons()
        {
            return DataManager.Get<PersonRepository>().GetAll();
        }

        IList<IPerson> ICoreService.GetPersons()
        {
            return GetPersons().OfType<IPerson>().ToList();
        }

        internal Person CreatePerson(string name, DateTime? dob)
        {
            Person person = new Person();
            UpdatePersonFields(person, name, dob);
            DataManager.Get<PersonRepository>().Insert(person);

            return person;
        }

        IPerson ICoreService.CreatePerson(string name, DateTime? dob)
        {
            using (ITransaction transaction = DataManager.BeginTransaction())
            {
                Person person = CreatePerson(name, dob);

                transaction.Commit();

                return person;
            }
        }

        internal void UpdatePerson(Person person, string name, DateTime? dob)
        {
            UpdatePersonFields(person, name, dob);
            DataManager.Get<PersonRepository>().Update(person);
        }

        private static void UpdatePersonFields(Person person, string name, DateTime? dob)
        {
            person.Name = name;
            person.DOB = dob;
        }

        IPerson ICoreService.UpdatePerson(int personID, string name, DateTime? dob)
        {
            using (ITransaction transaction = DataManager.BeginTransaction())
            {
                Person person = GetPerson(personID);
                UpdatePerson(person, name, dob);

                transaction.Commit();

                return person;
            }
        }

        internal void DeletePerson(Person person)
        {
            DataManager.Get<PersonRepository>().Delete(person);
        }

        void ICoreService.DeletePerson(int personID)
        {
            using (ITransaction transaction = DataManager.BeginTransaction())
            {
                DeletePerson(GetPerson(personID));

                transaction.Commit();
            }
        }
    }
}
